package com.snowfield.lbcommon.utils;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.Charset;
import java.util.Date;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Properties;

/**
 * 属性文件读写类
 *
 * @author snowfield 2024-06-07
 */
public class PropertiesProxy {
    private static final Logger LOGGER = LoggerFactory.getLogger(PropertiesProxy.class);
    private OrderedProperties properties = new OrderedProperties();

    private String proFilePath;//属性文件的路径

    public PropertiesProxy(String filePath) {
        try {
            this.proFilePath = filePath;
            if (properties == null) {
                properties = new OrderedProperties();
            }
            File proFile = new File(this.proFilePath);
            if (proFile.exists()) {
//                proFile.createNewFile();
                FileInputStream in = new FileInputStream(proFile);
                BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
                properties.load(br);

                br.close();
                in.close();
            }
        } catch (Exception e) {
            LOGGER.error("", e);
        }
    }

    /**
     * 查看是否包含属性key
     * @param key
     * @return
     */
    public Boolean hasProperty(String key){
        return properties.hasProperty(key);
    }

    /**
     * 根据key从属性文件中得到value
     *
     * @param key
     * @return
     */
    public Boolean getBooleanProperty(String key, Boolean defaultValue) {
        String value = properties.getProperty(key);
        Boolean reVal = defaultValue;

        if (value == null) {
            return reVal;
        } else {
            try {
                reVal = Boolean.valueOf(value);
            } catch (Exception e) {
            }
        }
        return reVal;
    }

    /**
     * 根据key从属性文件中得到value
     *
     * @param key
     * @return
     */
    public Integer getIntegerProperty(String key, Integer defaultValue) {
        String value = properties.getProperty(key);
        Integer reVal = defaultValue;

        if (value == null) {
            return reVal;
        } else {
            try {
                reVal = Integer.valueOf(value);
            } catch (Exception e) {
            }
        }
        return reVal;
    }

    /**
     * 根据key从属性文件中得到value
     *
     * @param key
     * @return
     */
    public Long getLongProperty(String key, Long defaultValue) {
        String value = properties.getProperty(key);
        Long reVal = defaultValue;

        if (value == null) {
            return reVal;
        } else {
            try {
                reVal = Long.valueOf(value);
            } catch (Exception e) {
            }
        }
        return reVal;
    }

    /**
     * 根据key从属性文件中得到value
     *
     * @param key
     * @return
     */
    public String getStringProperty(String key, String defaultValue) {
        String value = properties.getProperty(key);
        return value == null ? defaultValue : value;
    }

    /**
     * 修改key键值的值为value
     *
     * @param key
     * @param value
     */
    public void setProperty(String key, String value) {
        try {
            if (properties == null) {
                properties = new OrderedProperties();
            }

            properties.setProperty(key, value);
        } catch (Exception e) {
            LOGGER.error("", e);
        }
    }

    /**
     * 删除key键值
     *
     * @param key
     */
    public void removeProperty(String key) {
        try {
            if (properties == null) {
                return;
            }
            properties.remove(key);
        } catch (Exception e) {
            LOGGER.error("", e);
        }
    }

    /**
     * 保存数据
     * 默认进行特殊字符转义
     */
    public void store() {
        this.store(Boolean.TRUE);
    }

    /**
     * 保存数据
     * <p>
     * Properties类生成的键值对有两种分隔符，一是":"，一是"="
     * 如果值中有这两种字符时，要进行转义为"\:","\=",
     * 如果生成的文件只是用于存储数据，读取也是使用Properties来读取的话，转不转义都可以；
     * 在有的情况下，如果进行了转义，由其它系统读取时，可能无法识别转义后的字符，导致错误，比如值为mac地址时,本方法可适用此情况
     *
     * @param escape 是否进行转义
     */
    public void store(Boolean escape) {
        try {
            if (properties == null) {
                return;
            }
            File proFile = new File(this.proFilePath);
            if (!proFile.exists()) {
                proFile.createNewFile();
            }
            if (escape) {
                //对":"、"="进行转义时,转义为"\:"、"\="
                /**
                 * 使用FileWriter的话，如果文件中含有中文，也会正常显示
                 */
                FileWriter fw = new FileWriter(proFile);
                properties.store(fw, null);
                fw.flush();
                fw.close();
            } else {
                //不对":"、"="进行转义时
                StringBuilder fileContents = new StringBuilder();
                fileContents.append("#" + new Date().toString() + System.lineSeparator());
                Enumeration<?> propertyNames = properties.propertyNames();
                while (propertyNames.hasMoreElements()) {
                    String propertyName = (String) propertyNames.nextElement();
                    String propertyValue = properties.getProperty(propertyName);

                    String lineContent = propertyName + "=" + propertyValue + System.lineSeparator();
                    fileContents.append(lineContent);
                }
                FileUtils.writeStringToFile(proFile, fileContents.toString(), Charset.forName("UTF-8"));
            }
        } catch (Exception e) {
            LOGGER.error("", e);
        }
    }

    /**
     * 获取所有的键值对
     */
    public LinkedHashMap<String, String> getAll() {
        LinkedHashMap<String, String> allKV = new LinkedHashMap<>();
        Enumeration<?> e = properties.propertyNames();
        while (e.hasMoreElements()) {
            String key = (String) e.nextElement();
            String value = properties.getProperty(key);
            allKV.put(key, value);
        }

        return allKV;
    }

}
